namespace IconPatcher
{
    using System;
    using System.IO;
    using System.Linq;

    using IconPatcher.Annotations;

    [UsedImplicitly]
    public class RestoreDlls : BetterConsoleCommand
    {
        private string InstallPath;
        private VisualStudioVersion Version;

        private string[] Languages;

        private int ActionedCounter;
        private int SkippedCounter;

        public RestoreDlls()
        {
            IsCommand("restore", "Restores the backup DLLs for the specified version of Visual Studio.");

            HasRequiredOption("v|version=", "The version of Visual Studio to use (2010 or 2012).", v => Version = Helpers.ToVersion(v));
        }

        public override int Run(string[] remainingArguments)
        {
            if (Version == VisualStudioVersion.VS2010 && !Program.Support2010)
            {
                Console.WriteLine("You cannot run this command while in inject mode.");
                return 1;
            }

            if (Version == VisualStudioVersion.VS2012 && !Program.Support2012)
            {
                Console.WriteLine("You cannot run this command while in extract mode.");
                return 1;
            }

            var status = Helpers.GetInstallPath(Version, out InstallPath);
            if (status != 0)
            {
                return status;
            }

            Languages = GetLanguagess(Version);

            var dlls = (from d in Helpers.DllList
                        group d by d.Path
                        into g
                        select g.First()).ToList();
            dlls.ForEach(ProcessDll);

            Helpers.ClearImageCache(Version);

            Console.WriteLine("Restored {0:N0} files, skipped {1:N0} files", ActionedCounter, SkippedCounter);

            return 0;
        }

        private void ProcessDll(DllInformation dll)
        {
            if (!dll.SupportsCulture)
            {
                ProcessDll("1033", dll);
                return;
            }

            foreach (var language in Languages)
            {
                ProcessDll(language, dll);
            }
        }

        private void ProcessDll(string language, DllInformation dll)
        {
            var source = Path.Combine(InstallPath, dll.ExpandedPath(language));
            if (!File.Exists(source))
            {
                LogMessage("File not found: {0}", source.Remove(InstallPath));
                return;
            }

            var backup = source + ".orig";

            if (!File.Exists(backup))
            {
                Console.WriteLine("Backup file not found, skipping: {0}", backup.Remove(InstallPath));

                SkippedCounter++;
            }
            else
            {
                File.Copy(backup, source, true);

                LogMessage("Restored: {0}", source.Remove(InstallPath));

                ActionedCounter++;
            }
        }
    }
}